<template><div><h2 id="什么是作用域" tabindex="-1"><a class="header-anchor" href="#什么是作用域"><span>什么是作用域</span></a></h2>
<p><strong>通常来说，作用域就是限制一个变量在程序中的使用范围</strong></p>
<h2 id="js的作用域与函数作用域链" tabindex="-1"><a class="header-anchor" href="#js的作用域与函数作用域链"><span>js的作用域与函数作用域链</span></a></h2>
<p><em>js常见有三种作用域，但是还有更多详见<a href="https://cloud.tencent.com/developer/article/2212250" target="_blank" rel="noopener noreferrer">JS 的 9 种作用域，你能说出几种？-腾讯云开发者社区-腾讯云</a></em></p>
<ul>
<li><strong>全局作用域</strong> 在代码中最外层声明的变量或函数属于全局作用域，可以在程序的任何地方访问和修改。</li>
<li><strong>函数作用域</strong> 在函数内部声明的变量，仅在该函数内部有效，外部无法访问。每调用一次函数，都会创建新的作用域。函数执行完毕，局部变量销毁。</li>
<li><strong>块级作用域</strong> 块级作用域是 ES6 引入的，任何一对 {} 包裹的代码块（如 if 语句、for 循环、函数内部）都有自己的作用域。使用 let 和 const 声明的变量仅在块内有效。</li>
</ul>
<blockquote>
<p>函数作用域算是另一种块级作用域，具有块级作用域的所有特性，同时会限制var变量</p>
</blockquote>
<p><em><strong>作用域链</strong>是指当前作用域无法找到变量时，依次向上查找父级作用域，直到找到为止。如果查找到全局作用域还没有找到，则会抛出 ReferenceError 错误。</em></p>
<h3 id="几种声明关键字的不同" tabindex="-1"><a class="header-anchor" href="#几种声明关键字的不同"><span>几种声明关键字的不同</span></a></h3>
<p><em>首先我们要知道生命周期的概念。 每一个变量的创建都有一个生命周期：即声明，初始化，赋值。</em></p>
<p><em>声明就是标记这个变量存在，初始化就是为这个变量开辟一个内存空间，赋值就是往这个内存空间放入值</em></p>
<ul>
<li><strong>var 声明的变量作用域为函数作用域，同时变量会存在声明提升，初始化提升，值为undefined，此时我们可以在声明之前访问，不会报错，这被称之为变量提升</strong></li>
<li><strong>let ES6新提出的关键字，声明的变量作用域为块级作用域，仅有声明提升，此时我们在声明之前访问会报错，提示变量未被实例化，这被称之为暂时性死区 --TDZ</strong></li>
<li><strong>const 同上let，只不过赋值后无法再进行二次赋值</strong></li>
<li><strong>function 声明的是一种特殊的函数变量（可以理解成js代码串），声明的变量会存在声明提升，初始化提升，赋值提升，且优先级比var高</strong></li>
<li><strong>class ES6新引入的关键字，存在声明提升，本质上是基于function的语法糖<a href="https://blog.csdn.net/weixin_43850639/article/details/130652571" target="_blank" rel="noopener noreferrer">class其实是function的语法糖，底层继承实现还是基于原型链_class 是函数语法糖-CSDN博客</a></strong></li>
</ul>
<blockquote>
<p>参考：</p>
<p><a href="https://juejin.cn/post/7209939789808812093" target="_blank" rel="noopener noreferrer">5分钟告诉你let和const也有“变量提升”函数：声明提升，初始化提升，赋值提升。 var：声明提升，初始化提升。执行 - 掘金</a></p>
</blockquote>
<h2 id="global和window" tabindex="-1"><a class="header-anchor" href="#global和window"><span>global和window</span></a></h2>
<p>在浏览器环境下，全局对象是window，在node环境下，全局对象是global</p>
<h3 id="node和浏览器环境下this指向问题" tabindex="-1"><a class="header-anchor" href="#node和浏览器环境下this指向问题"><span>node和浏览器环境下this指向问题</span></a></h3>
<p>详见</p>
<p><a href="https://blog.csdn.net/nullccc/article/details/108931703" target="_blank" rel="noopener noreferrer">node的this和浏览器的this指向的区别_node 和 window的this执行环境差异-CSDN博客</a></p>
<p><a href="https://blog.csdn.net/aa96cpv/article/details/131152692" target="_blank" rel="noopener noreferrer">彻底搞懂浏览器和node.js中的this指向问题！-CSDN博客</a></p>
<p>简单来说，this的定义是当前运行的环境！本质上所有的函数都是通过对象调用，所以最终是谁调用的函数，函数内部的this就是谁。</p>
<p>在浏览器环境下，this绝大多数指向都是他们的调用对象（绝大多数都是window）,特殊的是在node环境下，this默认指的当前环境是module.exports，因为node把任意一个js文件都看作是一个模块。</p>
<p><em><strong>如果我们在new后面使用function关键字，会改变this指向详见<a href="https://blog.csdn.net/turnhead/article/details/32333771" target="_blank" rel="noopener noreferrer">prototype详解及prototype、new之间的关系_js prototype作用-CSDN博客</a></strong></em></p>
<h3 id="common-module-和es-module的区别" tabindex="-1"><a class="header-anchor" href="#common-module-和es-module的区别"><span>Common Module 和ES Module的区别</span></a></h3>
<p>Common Module使用module.exports 或者exports 关键字进行变量的导出，本质上默认会存在一个module对象，一个属性是exports(exports一开始module.exports的引用，本质上这俩关键字是一样的，但是不要对exports进行赋值操作)，使用require函数对模块文件的module.exports这一个值进行拷贝。</p>
<p>ESModule使用export关键字后面必须跟声明变量的关键字（let ,var,const，function），本质上在创建变量，并把地址返回，使用import关键字获取这些导出变量的地址（import 如果不拆箱的话，默认获得的是export default的地址）</p>
<p>node默认只能使用Common Module规范，如果想使用ES Module一般三种策略</p>
<ol>
<li>node环境集成Babel</li>
<li>node环境集成webpack</li>
<li>将所有ES Module规范的js模块文件后缀名修改为.mjs</li>
</ol>
<blockquote>
<p>参考：</p>
<p><a href="https://zhuanlan.zhihu.com/p/480929351" target="_blank" rel="noopener noreferrer">【混淆系列】module.exports、exports、export有什么区别？ - 知乎</a></p>
<p><a href="https://juejin.cn/post/7345792819753893940" target="_blank" rel="noopener noreferrer">面试官：聊聊ESModule的工作流程和实现原理ESModule的工作流程主要包含以下三个步骤： 构造(Construc - 掘金</a></p>
<p><a href="https://www.cnblogs.com/ifaswind/p/javascript-memory.html" target="_blank" rel="noopener noreferrer">JavaScript 内存详解 &amp; 分析指南 - 文弱书生陈皮皮 - 博客园</a></p>
<p><a href="https://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html" target="_blank" rel="noopener noreferrer">学习Javascript闭包（Closure） - 阮一峰的网络日志</a></p>
<p><a href="https://www.ruanyifeng.com/blog/2018/06/javascript-this.html" target="_blank" rel="noopener noreferrer">JavaScript 的 this 原理 - 阮一峰的网络日志</a></p>
<p><a href="https://mp.weixin.qq.com/s/3sm7wugUZ0GUavQsbQnEeg" target="_blank" rel="noopener noreferrer">一文理解 this、call、apply、bind</a></p>
<p><a href="https://segmentfault.com/a/1190000023356598" target="_blank" rel="noopener noreferrer">深入理解JavaScript闭包之什么是闭包 - 前端小码农 - SegmentFault 思否</a></p>
<p><a href="https://juejin.cn/post/7195098658583838777" target="_blank" rel="noopener noreferrer">我终于搞懂JS的模块化了！模块化，顾名思义，就是将相同功能的代码封装为一个功能模块，以便在其他地方多次进行复用，JS的模 - 掘金</a></p>
<p><a href="https://segmentfault.com/a/1190000017466120" target="_blank" rel="noopener noreferrer">javascript - 前端模块化详解(完整版) - 前端工匠公众号 - SegmentFault 思否</a></p>
</blockquote>
</div></template>


